package com.buba.shirodemo.config;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import net.sf.ehcache.CacheManager;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
public class ShiroConfig {
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("getDefaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        //设置安全管理器
        bean.setSecurityManager(defaultWebSecurityManager);
        //添加shiro的内置过滤器
         /*
            anon：无需认证就可以访问
            authc:必须认证了才能访问
            user:必须拥有 记住我功能才能用
            perms:拥有对某个资源的权限才能访问
            role：拥有某个角色权限才能访问
        */
        Map<String, String> filterMap=new LinkedHashMap<>();
        // 设置哪些路径授予哪些权限
        filterMap.put("/user/add","perms[1]");
        filterMap.put("/user/upd","perms[2]");
        // /user/* 指的是路径 必须认证了才能访问
        filterMap.put("/user/*","authc");
        bean.setFilterChainDefinitionMap(filterMap);
        // 设置登录的请求
        bean.setLoginUrl("/toLogin");
        // 跳转至未授权页面
        bean.setUnauthorizedUrl("/notea");
        return bean;
    }
    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //关联UserRealm
        securityManager.setRealm(userRealm);
        return  securityManager;
    }
    //创建Realm对象
    //创建realm对象，需要自定义类 1
    @Bean
    public UserRealm userRealm(@Qualifier("credentialsMatcher") HashedCredentialsMatcher matcher) {
        UserRealm userRealm = new UserRealm();
        //自定义密码比较器
        userRealm.setCredentialsMatcher(matcher);

        return userRealm;
    }
    //整合Shiro thymyleft
    @Bean
    public ShiroDialect getShiroDialect(){
        return new ShiroDialect();
    }
    /**
     * 替换当前 Realm 的 credentialsMatcher 属性.
     * 直接使用 HashedCredentialsMatcher 对象, 并设置加密算法即可.
     * 密码校验规则HashedCredentialsMatcher
     * 这个类是为了对密码进行编码的
     * 防止密码在数据库中明码表示,当然在登录认证的时候,
     * 这个类也负责对form里输入的密码进行编码
     * 处理认证匹配处理器
     */
    @Bean("credentialsMatcher")
    public HashedCredentialsMatcher credentialsMatcher() {
        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
        //设置加密算法
        matcher.setHashAlgorithmName("MD5");
        //设置加密次数
        matcher.setHashIterations(1000);
        //是否存储为16进制
        //将setStoredCredentialsHexEncoded设置为true，则需要使用toHex()进行转换成字符串，默认使用的是toBase64()
        matcher.setStoredCredentialsHexEncoded(true);
        return matcher;
    }

    /**
     * 密码超过五次限制登录的比较器
     * @return
     */
//    @Bean("credentialsMatcher")
//    public RetryLimitHashedCredentialsMatcher retryLimitHashedCredentialsMatcher(){
//        RetryLimitHashedCredentialsMatcher retryLimitHashedCredentialsMatcher = new RetryLimitHashedCredentialsMatcher(ehCacheManager());
//
////        如果密码加密,可以打开下面配置
////        加密算法的名称
//        retryLimitHashedCredentialsMatcher.setHashAlgorithmName("MD5");
////        配置加密的次数
//        retryLimitHashedCredentialsMatcher.setHashIterations(1024);
////        是否存储为16进制
//        retryLimitHashedCredentialsMatcher.setStoredCredentialsHexEncoded(true);
//
//        return retryLimitHashedCredentialsMatcher;
//    }

    /**
     * EhCacheManager配置
     * @return
     */
//    @Bean
//    public EhCacheManager ehCacheManager() {
//        //注意myEhcache对应上面的<ehcache name="myEhcache">
//        CacheManager cacheManager = new CacheManager();
//        if(cacheManager == null){
//            cacheManager = CacheManager.create();
//        }
//        EhCacheManager ehCacheManager = new EhCacheManager();
//        ehCacheManager.setCacheManager(cacheManager);
//        return ehCacheManager;
//    }


}

